package com.xiaoxie.system.aspect;

import com.xiaoxie.system.annatotion.SetDS;
import com.xiaoxie.system.datasource.DynamicDataSourceManager;
import jakarta.annotation.Resource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class SetDsAspect {

    // 切入点
    @Pointcut("@annotation(com.xiaoxie.system.annatotion.SetDS) && execution(* com.xiaoxie..service.*.*(..))")
    private void pointCut(){}

    // 前置通知
    @Before("pointCut()")
    public void beforeAdvice(JoinPoint joinPoint) {
        // 获得目标方法
        Method method = getMethod(joinPoint);
        if (method != null) {
            // 获取方法参数
            Object[] args = joinPoint.getArgs();

            // 判断参数是否存在，如果存在且第一个参数是String类型
            if (args != null && args.length > 0 && args[0] instanceof String) {
                DynamicDataSourceManager.setDataSource(args[0].toString());
            } else {
                // 获取注解
                SetDS setDS = method.getAnnotation(SetDS.class);
                if (setDS != null) {
                    // 获取注解的值
                    String value = setDS.value();
                    // 设置数据源
                    DynamicDataSourceManager.setDataSource(value);
                }
            }
        }
    }

    @After("pointCut()")
    public void afterAdvice(JoinPoint joinPoint) {
        // 获得目标方法
        Method method = getMethod(joinPoint);
        if (method != null) {
            // 获取方法参数
            Object[] args = joinPoint.getArgs();
            // 判断参数是否存在，如果存在且第一个参数是String 类型
            if (args != null && args.length > 0 && args[0] instanceof String ) {
                DynamicDataSourceManager.clearDataSource();
            } else {
                // 获取注解
                SetDS setDS = method.getAnnotation(SetDS.class);
                if (setDS != null) {
                    // 设置数据源
                    DynamicDataSourceManager.clearDataSource();
                }
            }

        }
    }


    private Method getMethod(JoinPoint joinPoint) {
        try {
            // 获取目标类
            Class<?> targetClass = joinPoint.getTarget().getClass();
            // 获取方法签名
            String methodName = joinPoint.getSignature().getName();
            // 获取方法参数类型
            Object[] args = joinPoint.getArgs();
            Class<?>[] argTypes = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = args[i].getClass();
            }
            // 返回方法对象
            return targetClass.getMethod(methodName, argTypes);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
}
